package com.isoft.airportsystem.controller.system;

import com.isoft.airportsystem.common.Result;
import com.isoft.airportsystem.dto.LoginRequest;
import com.isoft.airportsystem.entity.system.User;
import com.isoft.airportsystem.entity.system.Role;
import com.isoft.airportsystem.service.system.UserService;
import com.isoft.airportsystem.util.JwtUtil;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Value;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 登录控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/system")
@CrossOrigin(origins = {"http://localhost:8080", "http://localhost:3000", "http://localhost:5173"}, allowCredentials = "true")
public class LoginController {

    @Autowired
    private UserService userService;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String mailFrom;

    /**
     * 用户登录 - 使用DTO对象接收参数
     *
     * @param loginRequest 登录请求对象
     * @return 登录结果
     */

    @PostMapping("/login")
    public Result<Map<String, Object>> login(@Valid @RequestBody LoginRequest loginRequest, HttpSession session) {
        // 验证码校验
        String inputCaptcha = loginRequest.getCaptcha();
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if (sessionCaptcha == null || !sessionCaptcha.equals(inputCaptcha)) {
            return Result.error(400, "验证码错误");
        }
        // 提取参数
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();

        // 添加详细的请求日志
        log.debug("收到登录请求 - username: '{}', password: {}", username, (password != null) ? "***" : "null");
        log.info("接收参数 - username: [{}], password: [{}]",
                username, (password != null) ? "***" + password.length() + " chars" : "NULL");

        // 参数验证 - 确保用户名和密码存在且不为空
        if (!StringUtils.hasText(username)) {
            log.warn("登录失败: 用户名为空");
            return Result.error(400, "用户名不能为空");
        }
        if (!StringUtils.hasText(password)) {
            log.warn("登录失败: 用户 '{}' 密码为空", username);
            return Result.error(400, "密码不能为空");
        }


        // 根据用户名查询用户
        User user = userService.selectUserByUsername(username);
        if (user == null) {
            // 安全优化：避免提示具体错误信息
            log.warn("登录失败: 用户 '{}' 不存在", username);
            return Result.error(401, "用户名或密码错误");
        }

        // 验证密码
        String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!encryptedPassword.equals(user.getPassword())) {
            // 安全优化：避免提示具体错误信息
            log.warn("登录失败: 用户 '{}' 密码错误", username);
            return Result.error(401, "用户名或密码错误");
        }

        // 验证用户状态
        if (user.getStatus() != 1) {
            log.warn("登录失败: 用户 '{}' 已被禁用", username);
            return Result.error(403, "用户已被禁用");
        }

        // 获取用户权限
        List<String> permissions = userService.selectPermissionsByUserId(user.getUserId());

        // 获取用户角色
        List<Role> roles = userService.selectRolesByUserId(user.getUserId());

        // 生成JWT Token
        String token = jwtUtil.generateToken(user.getUserId(), user.getUsername());

        // 构建返回结果
        Map<String, Object> data = new HashMap<>();
        data.put("userId", user.getUserId());
        data.put("username", user.getUsername());
        data.put("realName", user.getRealName());
        data.put("avatar", user.getAvatar());
        data.put("permissions", permissions);
        data.put("roles", roles);
        data.put("identity", user.getRemark());
        data.put("token", token);

        session.setAttribute("userId", user.getUserId()); // 登录成功后存入session

        log.info("登录成功: 用户 '{}'", username);
        return Result.success("登录成功", data);
    }

    /**
     * 获取用户信息
     *
     * @param userId 用户ID
     * @return 用户信息
     */
    @GetMapping("/getUserInfo")
    public Result<Map<String, Object>> getUserInfo(@RequestParam(required = false) Long userId) {
        // 参数验证
        if (userId == null) {
            log.warn("获取用户信息失败: 用户ID为空");
            return Result.error(400, "用户ID不能为空");
        }

        // 根据用户ID查询用户
        User user = userService.getById(userId);
        if (user == null) {
            log.warn("获取用户信息失败: 用户ID '{}' 不存在", userId);
            return Result.error(404, "用户不存在");
        }

        // 获取用户权限
        List<String> permissions = userService.selectPermissionsByUserId(userId);

        // 获取用户角色
        List<Role> roles = userService.selectRolesByUserId(userId);

        // 构建返回结果
        Map<String, Object> data = new HashMap<>();
        data.put("userId", user.getUserId());
        data.put("username", user.getUsername());
        data.put("realName", user.getRealName());
        data.put("avatar", user.getAvatar());
        data.put("permissions", permissions);
        data.put("roles", roles);
        data.put("identity", user.getRemark());

        log.debug("获取用户信息成功: 用户ID '{}'", userId);
        return Result.success(data);
    }

    /**
     * 用户登出
     *
     * @return 登出结果
     */
    @PostMapping("/logout")
    public Result<Void> logout() {
        // 这里可以添加登出逻辑，如清除会话等
        log.info("用户登出成功");
        return Result.success("登出成功");
    }

    @PostMapping("/register")
    public Result<?> register(@RequestBody LoginRequest registerRequest, HttpSession session) {
        String username = registerRequest.getUsername();
        String password = registerRequest.getPassword();
        String email = registerRequest.getEmail();
        String emailCode = registerRequest.getCaptcha(); // 用captcha字段存邮箱验证码
        String identity = registerRequest.getIdentity(); // 用户身份

        // 参数校验
        if (!StringUtils.hasText(username)) {
            return Result.error(400, "用户名不能为空");
        }
        if (!StringUtils.hasText(password)) {
            return Result.error(400, "密码不能为空");
        }
        if (!StringUtils.hasText(email)) {
            return Result.error(400, "邮箱不能为空");
        }
        if (!StringUtils.hasText(emailCode)) {
            return Result.error(400, "邮箱验证码不能为空");
        }
        if (!StringUtils.hasText(identity)) {
            return Result.error(400, "用户身份不能为空");
        }

        // 校验邮箱验证码
        String sessionCode = (String) session.getAttribute("registerCode:" + email);
        if (sessionCode == null || !sessionCode.equals(emailCode)) {
            return Result.error(400, "邮箱验证码错误或已过期");
        }

        // 检查用户名是否已存在
        User existingUser = userService.selectUserByUsername(username);
        if (existingUser != null) {
            return Result.error(409, "用户名已存在");
        }
        // 不做邮箱唯一性校验

        // 根据身份确定角色ID
        Long roleId = null;
        if ("stu".equals(identity)) {
            // 普通用户 - 分配NORMAL_USER角色
            roleId = 3L; // 根据数据库脚本，普通用户角色ID为3
        } else if ("dormManager".equals(identity)) {
            // 管理员 - 分配SUPER_ADMIN角色（超级管理员）
            roleId = 1L; // 根据数据库脚本，超级管理员角色ID为1
        } else {
            return Result.error(400, "无效的用户身份");
        }

        // 创建新用户
        User newUser = new User();
        newUser.setUsername(username);
        newUser.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        newUser.setStatus(1); // 启用
        newUser.setRemark(identity);
        newUser.setEmail(email);

        // 使用insertUser方法，同时分配角色
        boolean success = userService.insertUser(newUser, new Long[]{roleId});

        if (!success) {
            return Result.error(500, "注册失败，请稍后重试");
        }

        // 注册成功后移除验证码
        session.removeAttribute("registerCode:" + email);

        return Result.success("注册成功");
    }

    @GetMapping("/captcha")
    public Result<Map<String, Object>> getCaptcha(HttpSession session) {
        Random rand = new Random();
        int a = rand.nextInt(10);
        int b = rand.nextInt(10);
        int result = a + b;
        String captchaText = a + " + " + b + " = ?";
        session.setAttribute("captcha", String.valueOf(result));
        Map<String, Object> data = new HashMap<>();
        data.put("captcha", captchaText);
        return Result.success(data);
    }

    @PostMapping("/sendResetCode")
    public Result<?> sendResetCode(@RequestBody Map<String, String> req, HttpSession session) {
        String email = req.get("email");
        if (!StringUtils.hasText(email)) {
            return Result.error(400, "邮箱不能为空");
        }
        // 只根据邮箱查用户
        User user = userService.lambdaQuery().eq(User::getEmail, email).one();
        if (user == null) {
            return Result.error(404, "该邮箱未注册");
        }
        // 生成验证码
        String code = String.valueOf(new Random().nextInt(899999) + 100000);
        session.setAttribute("resetCode:" + email, code);
        // 发送邮件验证码
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(mailFrom);
            helper.setTo(email);
            helper.setSubject("找回密码验证码");
            helper.setText("验证码：" + code, false);
            mailSender.send(message);
            log.info("验证码 {} 已发送到邮箱 {}", code, email);
        } catch (MessagingException e) {
            log.error("发送邮件失败", e);
            return Result.error(500, "邮件发送失败，请稍后重试");
        }
        return Result.success("验证码已发送");
    }

    @PostMapping("/resetPassword")
    public Result<?> resetPassword(@RequestBody Map<String, String> req, HttpSession session) {
        String email = req.get("email");
        String code = req.get("code");
        String newPassword = req.get("newPassword");
        if (!StringUtils.hasText(email) || !StringUtils.hasText(code) || !StringUtils.hasText(newPassword)) {
            return Result.error(400, "参数不能为空");
        }
        User user = userService.lambdaQuery().eq(User::getEmail, email).one();
        if (user == null) {
            return Result.error(404, "该邮箱未注册");
        }
        String sessionCode = (String) session.getAttribute("resetCode:" + email);
        if (sessionCode == null || !sessionCode.equals(code)) {
            return Result.error(400, "验证码错误或已过期");
        }
        // 更新密码
        user.setPassword(DigestUtils.md5DigestAsHex(newPassword.getBytes()));
        userService.updateUserSelective(user);
        session.removeAttribute("resetCode:" + email);
        return Result.success("密码重置成功");
    }

    @PostMapping("/sendEmailCode")
    public Result<?> sendEmailCode(@RequestBody Map<String, String> req, HttpSession session) {
        String email = req.get("email");
        if (!StringUtils.hasText(email)) {
            return Result.error(400, "邮箱不能为空");
        }
        // 生成验证码
        String code = String.valueOf(new Random().nextInt(899999) + 100000);
        session.setAttribute("registerCode:" + email, code);
        // 发送邮件验证码
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(mailFrom);
            helper.setTo(email);
            helper.setSubject("注册验证码");
            helper.setText("您的注册验证码是：" + code + "，5分钟内有效。", false);
            mailSender.send(message);
            log.info("注册验证码 {} 已发送到邮箱 {}", code, email);
        } catch (MessagingException e) {
            log.error("发送邮件失败", e);
            return Result.error(500, "邮件发送失败，请稍后重试");
        }
        return Result.success("验证码已发送");
    }
}